<script lang="ts" setup>
import type { Recordable } from '@vben/types';

import { onMounted, reactive, ref } from 'vue';

import { ColPage } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';

import { useLoading } from '@vben-core/shadcn-ui';

import { useFs } from '@fast-crud/fast-crud';
import {
  Alert,
  Button,
  Card,
  Image,
  TabPane,
  Tabs,
  Tooltip,
} from 'ant-design-vue';

import { getValidateRulesByFs } from '#/api/common/validateByFs';
import {
  DefGenProjectApi,
  DefGenProjectConfig,
} from '#/api/devOperation/developer/defGenProject';
import { ActionEnum } from '#/enums/commonEnum';
import { useMessage } from '#/hooks/web/useMessage';
import { blobToObj, downloadByResponse } from '#/utils/file/download';

import { createCrudOptions, frontRules } from './data/crud';

const formRef = ref();
const activeKey = ref<string>('type');
const tabList = ref<any[]>([
  { key: 'type', name: '项目类型' },
  { key: 'outputDir', name: '输出路径' },
  { key: 'author', name: '作者' },
  { key: 'projectPrefix', name: '项目前缀' },
  { key: 'serviceName', name: '服务名' },
  { key: 'parent', name: '基础包' },
  { key: 'moduleName', name: '模块名' },
  { key: 'groupId', name: 'groupId' },
  { key: 'utilParent', name: 'util基础包' },
  { key: 'utilGroupId', name: 'utilGroupId' },
  { key: 'version', name: '版本号' },
  { key: 'description', name: '中文服务名' },
  { key: 'serverPort', name: '端口号' },
]);
const colPageProps = reactive({
  leftCollapsedWidth: 5,
  // 左侧最大宽度百分比
  leftMaxWidth: 90,
  // 左侧最小宽度百分比
  leftMinWidth: 10,
  leftWidth: 60,
  rightWidth: 40,
  // 左侧可折叠
  leftCollapsible: true,
  // 显示拖动手柄
  splitHandle: true,
  // 可拖动调整宽度
  resizable: true,
  // 显示拖动分隔线
  splitLine: true,
});

const images: Record<string, any> = import.meta.glob(
  '../../../../assets/project/*.{png,jpg}',
  { eager: true },
);
const imgModules: Recordable = {};
const { createMessage } = useMessage();

Object.keys(images).forEach((key) => {
  const mod = images[key]?.default;
  const name = key.slice(key.lastIndexOf('/') + 1, key.lastIndexOf('.'));
  imgModules[name] = mod;
});
function changeTab(key: string) {
  activeKey.value = key;
}

const [openFullLoading, closeFullLoading] = useLoading({
  text: '加载中...',
});

const { crudBinding, appendCrudOptions } = useFs({
  createCrudOptions,
  context: { changeTab },
});

const load = async () => {
  try {
    openFullLoading();
    const record = await DefGenProjectApi.getDef();
    formRef.value.setFormData(record);

    const addFormOptions = await getValidateRulesByFs({
      Api: DefGenProjectConfig.Generator,
      mode: ActionEnum.ADD,
      customRules: frontRules.editForm.rules,
      trigger: 'change',
    });
    appendCrudOptions({ ...addFormOptions });
  } finally {
    closeFullLoading();
  }
};
// 页面打开后获取列表数据
onMounted(async () => {
  await load();
});

async function handleSubmit() {
  try {
    openFullLoading();
    await formRef.value.submit();
    createMessage.success('生成成功');
  } finally {
    closeFullLoading();
  }
}

async function handleDownload() {
  await formRef.value.formRef.validate();
  try {
    openFullLoading();
    const params = formRef.value.getFormData();
    const response = await DefGenProjectApi.download(params);
    if (response) {
      downloadByResponse(response);
      createMessage.success('下载成功');
    } else {
      createMessage.error(
        '下载失败，请认真检查【生成信息】是否填写完整并保存成功！',
      );
    }
  } catch (error: any) {
    if (error?.response?.data) {
      const obj = (await blobToObj(error?.response?.data)) as any;
      createMessage.error(obj.msg);
    } else {
      const obj = (await blobToObj(error)) as any;
      createMessage.error(obj.msg);
    }
  } finally {
    closeFullLoading();
  }
}

async function reset() {
  await load();
}

function clear() {
  formRef.value.reset();
}
</script>

<template>
  <ColPage v-bind="colPageProps">
    <template #left="{ isCollapsed, expand }">
      <div v-if="isCollapsed" @click="expand">
        <Tooltip title="点击展开左侧">
          <Button shape="circle" type="primary">
            <template #icon>
              <IconifyIcon class="text-2xl" icon="bi:arrow-right" />
            </template>
          </Button>
        </Tooltip>
      </div>
      <div
        v-else
        class="border-border bg-card mr-2 h-full rounded-[var(--radius)] border p-2"
      >
        <Card title="服务或模块生成">
          <FsForm ref="formRef" v-bind="crudBinding.addForm" />

          <Alert class="mt-2" message="注意事项" type="warning" show-icon>
            <template #description>
              <p>
                1. {基础包}.{模块名}
                需要和【代码生成】-【修改代码配置】中{父包名}.{模块名}一致，否则生成的服务swagger文档可能无法显示（需要手动调整）
              </p>
              <p>2. 若需要修改 groupId，需要和项目代码中的groupId中保持一致</p>
              <p>
                3. {基础包} 需要与启动类所在的基础包一致，否则需要修改项目中
                @ComponentScan和@MapperScan中的配置
              </p>
              <p>
                4. {本地生成}
                适用于开发者本地启动项目后，直接将"代码"生成在开发者所在电脑的“输出路径”所在目录。
              </p>
              <p>
                5. {远程下载}
                适用于测试环境启动项目后，开发者将生成的代码下载到开发者的电脑。
              </p>
            </template>
          </Alert>

          <template #extra>
            <Button class="mr-2" @click="clear">清空</Button>
            <Button class="mr-2" @click="reset">重置</Button>
            <Button type="primary" class="mr-2" @click="handleSubmit">
              本地生成
            </Button>
            <Button type="primary" @click="handleDownload">远程下载</Button>
          </template>
        </Card>
      </div>
    </template>
    <Tabs v-model:active-key="activeKey">
      <TabPane v-for="item in tabList" :key="item.key">
        <template #tab>
          {{ item.name }}
        </template>
        <Image :src="imgModules[item.key]" height="100%" width="100%" />
      </TabPane>
    </Tabs>
  </ColPage>
</template>
